/************* Iterative seeder ****************/
#include "header.h"
#include "dstruct.h"
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/signal.h>
#include<sys/time.h>
#include<sys/resource.h>
#include<sys/wait.h>
#include<sys/errno.h>
#include<netinet/in.h>
#include<netdb.h>

#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>

#define SEND_BUFF 1024

void seeder_server(int sock,struct file_part *head)
{
	struct file_part *temp = head;
	char ack_buff;
	char msg[50],buffer[SEND_BUFF];
	char filename[20],part[20];
	int i =0,len=0,part_num,no_of_pieces=0,size_counter=0;
	int part_size,read_count=0;	
	size_t bytes_read=0;
	pthread_mutex_t safe_seed;
#ifdef DEBUG
	printf("\nWaiting for file request from leecher.");
#endif
   recv(sock,msg,sizeof(msg),MSG_WAITALL); // receive the filename and part no from leecher.
   //parse the incoming message into tokens
   
#ifdef DEBUG
	printf("\nfile request from leecher received ... parsing.");	
#endif
	while(msg[i] != ','){
		filename[i] = msg[i];
		i++;
		len++;
	}
	filename[i] = '\0';
	i=0;
	len++;
	while(msg[len] != '$'){
		part[i] = msg[len];
		len++;
		i++;
	}
	part[i] = '\0';
	part_num = atoi(part);
#ifdef DEBUG
	printf("\nfile part requested by leecher is part:%d.",part_num);	
#endif	
	//calculate the number of pieces present in a file
	while(temp){
		no_of_pieces++;
		temp=temp->next;
	}
	temp = head;
	
	while(temp->part_num == part_num){
		temp=temp->next; // go to the requested file part node
	}

	//part_size = temp->file_size - (no_of_pieces* PARTSIZE);

	pthread_mutex_unlock(&safe_seed);

	temp->data_ptr = fopen(filename, "rb");
	if(!temp->data_ptr){
		printf("ERROR: Unable to open %s.No such file or directory\n",filename);
	}
	fseek(temp->data_ptr,0,SEEK_END);
	part_size = (int)ftell(temp->data_ptr);
	rewind(temp->data_ptr);

	pthread_mutex_lock(&safe_seed);
	//moving to the proper offset	
	fseek(temp->data_ptr,((part_num-1)*PARTSIZE),SEEK_SET);
	
	while(size_counter != part_size){
		pthread_mutex_lock(&safe_seed);
		bytes_read = fread(buffer,sizeof(char),SEND_BUFF,temp->data_ptr);
		pthread_mutex_unlock(&safe_seed);

		size_counter += bytes_read;
		read_count++;
		send(sock,buffer,bytes_read,0);
		recv(sock,&ack_buff,sizeof(ack_buff),MSG_WAITALL); // reason for &ack_buff: it is a char , but recv needs pointer
		if(ack_buff == 'P'){
			continue;
		}
		else if(ack_buff == 'N'){
			fseek(temp->data_ptr,-bytes_read,SEEK_CUR);
			size_counter -= bytes_read;
			read_count--;
		}
	}

	pthread_mutex_lock(&safe_seed);
	fclose(temp->data_ptr);
	pthread_mutex_unlock(&safe_seed);
	close(sock);
}
